﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;

namespace Skyhook.Core.Screens
{
    public class GameScreenManager : ApplicationComponent
    {
        LinkedList<GameScreen> Screens = new LinkedList<GameScreen>();
        
        public GameScreenManager()
            : base()
        {
        }

        protected override void Update(GameTime time)
        {
            bool updatedone = false;
            
            LinkedListNode<GameScreen> screen = Screens.Last;
            while(screen != null && !updatedone)
            {
                screen.Value.UpdateWithComponents(time);

                if (!screen.Value.IsVisible)
                {
                    screen.Value.DisconnectInputAndSaveStatus();

                    LinkedListNode<GameScreen> oldscreen = screen;
                    screen = screen.Previous;
                    Screens.Remove(oldscreen);

                    if (screen != null)
                    {
                        screen.Value.Activate();
                    }

                    continue;
                }

                if (!screen.Value.IsPopup)
                {
                    updatedone = true;
                }

                screen = screen.Previous;
            }

            if (Screens.Last != null && !Screens.Last.Value.HasInput)
            {
                Screens.Last.Value.ConnectInputAndSaveStatus();
            }
        }

        protected override void Draw(GameTime time)
        {
            LinkedListNode<GameScreen> currentscreen = Screens.First;
            while (currentscreen != null)
            {
                if (currentscreen.Value.IsVisible)
                {
                    currentscreen.Value.DrawWithComponents(time);
                }

                currentscreen = currentscreen.Next;
            }
        }

        protected override void Initialize()
        {
            foreach (GameScreen screen in Screens)
            {
                screen.InitializeWithComponents();
            }
        }

        protected override void LoadContent()
        {
            foreach (GameScreen screen in Screens)
            {
                screen.LoadContentWithComponents();
            }
        }

        protected override void UnloadContent()
        {
            foreach (GameScreen screen in Screens)
            {
                screen.UnloadContentWithComponents();
            }
        }

        internal void AddScreen(GameScreen screen)
        {
            if (IsInitialized)
            {
                screen.InitializeWithComponents();
            }

            if (IsContentLoaded)
            {
                screen.LoadContentWithComponents();
            }

            if (Screens.Last != null && Screens.Last.Value.HasInput)
            {
                Screens.Last.Value.DisconnectInputAndSaveStatus();
            }

            Screens.AddLast(screen);
        }

        internal void RemoveScreen(GameScreen screen)
        {
            if (IsContentLoaded)
            {
                screen.UnloadContentWithComponents();
            }

            Screens.Remove(screen);
        }

        public void HideAll()
        {
            foreach (GameScreen screen in Screens)
            {
                screen.Hide();
            }
        }

        public int ScreensCount
        {
            get
            {
                return Screens.Count;
            }
        }
    }
}
